// --- The "OOP Class" ---
// uuClass - create a simple class
uuClass = function(/* args, ... */) {
  // when "this" is referred in this scope, "this" is equal to window
  return function() {
    // when "this" is referred in this scope, "this" shows the instance newly generated
    this.construct && this.construct.apply(this, arguments);
  };
};

// uuClass.Generic - create a generic class
uuClass.Generic = function(/* args, ... */) {
  return function() {
    !("uuid" in this) && (this.uuid = uu.uuid()); // add "uuid" property
    this.msgbox && uu.msg && uu.msg.regist(this);
    this.construct && this.construct.apply(this, arguments);
    if (this.destruct) {
      var me = this, dest = function() { me.destruct(); };
      if (document.uniqueID) {
        window.attachEvent("onunload", dest);
      } else {
        window.addEventListener("unload", dest, false);
      }
    }
  };
};

// uuClass.Singleton - create a singleton class
uuClass.Singleton = function(/* args, ... */) {
  return function() {
    var me = this, a = arguments, fn = a.callee, dest;
    if (!fn.instance) {
      fn.instance = me; // keep instance
      !("uuid" in me) && (me.uuid = uu.uuid()); // add "uuid" property
      me.msgbox && uu.msg && uu.msg.regist(me);
      me.construct && me.construct.apply(me, a);
      if (me.destruct) {
        dest = function() { me.destruct(); };
        if (document.uniqueID) {
          window.attachEvent("onunload", dest);
        } else {
          window.addEventListener("unload", dest, false);
        }
      }
    } else {
      me.stabled && me.stabled.apply(me, a); // after the second
    }
    return fn.instance; // fn.instance is returned. "this" is abandoned.
  };
};
